package fr.adfm.managedbean;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.model.SelectItem;
import javax.faces.validator.ValidatorException;

import org.primefaces.event.FlowEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import fr.adfm.dto.AdresseDto;
import fr.adfm.dto.ArticlePanierDto;
import fr.adfm.dto.BonCommandeDto;
import fr.adfm.dto.PanierDto;
import fr.adfm.entity.BonCommande;
import fr.adfm.proxy.orquestrateur.PaiementManagementResponse;
import fr.adfm.service.facade.Facade;
import fr.adfm.utils.Utils;

@Component("commande")
@Scope("session")
public class CommandeCtrl implements Serializable {
	private static final long serialVersionUID = 1L;

    public String onFlowProcess(FlowEvent event) {
            return event.getNewStep();
    }

	@Autowired
	Facade facade;

	@Autowired
	private SessionManager sessionManager;


    // --------- Bean Business panier ---------------------

	public PanierDto getPanier() {
		return sessionManager.getPanier();
	}

	public ArticlePanierDto[] getAllArticlePanier(){
		Collection<ArticlePanierDto> articles =  getPanier().getArticles();
		return articles.toArray(new ArticlePanierDto[articles.size()]);
	}

	private int val;

	public int getVal() {
		return val;
	}
	public void setVal(int val) {
		this.val = val;
	}

	// ---------Bean Business Data Adresse Livraison----------
	private AdresseDto adresseLivraison = new AdresseDto();

	public AdresseDto getAdresseLivraison() {
		return adresseLivraison;
	}

	public void setAdresseLivraison(AdresseDto adresseLivraison) {
		this.adresseLivraison = adresseLivraison;
	}

	public void validateAdresse(FacesContext context, UIComponent component, Object value) {

		String rs = "";
		String prenom = "";
		String nom ="";
		Object val;
		for(UIComponent c : component.getParent().getChildren()){
			if(c.getId().equals("nom")){
				val = ((UIInput) c).getLocalValue();
				if(val != null) nom = val.toString().trim();
				continue;
			}
			if(c.getId().equals("prenom")){
				val = ((UIInput) c).getLocalValue();
				if(val != null) prenom = val.toString().trim();
				continue;
			}
			if(c.getId().equals("rs")){
				val = ((UIInput) c).getLocalValue();
				if(val != null) rs = val.toString().trim();
				continue;
			}
		}
		if((nom.length() + rs.length()) == 0){
			throw new ValidatorException(new FacesMessage("Nom ou Raison sociale non renseign�"));
		}

	}

	 // ---------Bean Business Data Mode Livraison----------
	private int optionModeLivraison = 1;

	public int getOptionModeLivraison() {
		return optionModeLivraison;
	}

	public void setOptionModeLivraison(int optionModeLivraison) {
		this.optionModeLivraison = optionModeLivraison;
	}

	public double getFraisDePort(){
		return (optionModeLivraison == 1) ? 2.0 : 5.0;
	}

	// ---------Bean Business Data commande----------
	public double getPrixPanier()
	{
		return getPanier().getPrix();
	}

	public double getTotalCommande() {
		Collection<ArticlePanierDto> articles = getPanier().getArticles();
		this.montantTotalCommande = getPanier().getPrix() + getFraisDePort();
		this.montantAutreDevise = this.montantTotalCommande
				* this.tauxAutreDevise;
		return montantTotalCommande;
	}

	public String create() {
			BonCommandeDto bonCommande =
				facade.getBonCommandeService().CreateBonCommande(
				sessionManager.getMembre(),
				getPanier(),
				adresseLivraison,
				getFraisDePort());

		System.out.println(bonCommande);

		PaiementManagementResponse paiementManagementResponse = facade.getOrquestrateurService().payer(bonCommande);
		String urlGoBanque ="";
		if(paiementManagementResponse.getEtatFinal().equals("PaiementWaiting"))
		{
			
			urlGoBanque = paiementManagementResponse.getUrlSitePaiement();
			System.out.println(urlGoBanque);
			getPanier().getArticles().clear();
			try {
				FacesContext.getCurrentInstance().getExternalContext().redirect(urlGoBanque);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return urlGoBanque;
		}
		else
		{
			
			return "stockInsuffisant.xhtml";
		}
		
	}

	//------------- devise -----------

	private String devise;
	private List devises = new ArrayList();
	private List<String> listeDevises = new ArrayList<String>();
	private double montantAutreDevise;
	private double montantTotalCommande;
	private double tauxAutreDevise;
	private String cheminWSExchange;
	private String strCurrencies;
	private String strRate;

	/**
	 * @return the montantTotalCommande
	 */
	public double getMontantTotalCommande() {
		return montantTotalCommande;
	}

	/**
	 * @param montantTotalCommande the montantTotalCommande to set
	 */
	public void setMontantTotalCommande(double montantTotalCommande) {
		this.montantTotalCommande = montantTotalCommande;
	}

	/**
	 * @return the tauxAutreDevise
	 */
	public double getTauxAutreDevise() {
		return tauxAutreDevise;
	}

	/**
	 * @param tauxAutreDevise the tauxAutreDevise to set
	 */
	public void setTauxAutreDevise(double tauxAutreDevise) {
		this.tauxAutreDevise = tauxAutreDevise;
	}

	/**
	 * @param montantAutreDevise the montantAutreDevise to set
	 */
	public void setMontantAutreDevise(double montantAutreDevise) {
		this.montantAutreDevise = montantAutreDevise;
	}

	@PostConstruct
	public void init() {
		String foreignCurrencies;

		String strUrl = Utils.getResourceByName("parametres", "wschange-url");
		String strPort = Utils.getResourceByName("parametres", "wschange-port");
		String strPattern = Utils.getResourceByName("parametres",
				"wschange-pattern");
		String strChange = Utils.getResourceByName("parametres",
				"wschange-change");
		strRate = Utils.getResourceByName("parametres", "wschange-rate");
		strCurrencies = Utils.getResourceByName("parametres",
				"wschange-currencies");
		cheminWSExchange = "http://" + strUrl + ":" + strPort + strPattern
				+ strChange;
		// appel WSCurrencyExchange recuperation de la liste de devises
		// disponibles echangeables depuis l'EURO
		foreignCurrencies = Utils.getStringContentByURL(cheminWSExchange
				+ strCurrencies);

		StringTokenizer stringTokenizer = new StringTokenizer(
				foreignCurrencies, " [],");
		while (stringTokenizer.hasMoreElements()) {
			listeDevises.add(stringTokenizer.nextElement().toString());
		}

	}

	public List getDevises() {
		devises.clear();
		SelectItem selectItem = new SelectItem();
		selectItem.setValue("?");
		selectItem.setLabel("?");
		devises.add(selectItem);

		devises.clear();
		for (String s : listeDevises) {
			selectItem = new SelectItem();
			selectItem.setValue(s);
			selectItem.setLabel(s);
			devises.add(selectItem);

		}

		// selectItem = new SelectItem();
		// selectItem.setValue("USD");
		// selectItem.setLabel("US Dollars");
		// devises.add(selectItem);
		//
		// selectItem = new SelectItem();
		// selectItem.setValue("GBP");
		// selectItem.setLabel("Livre Sterling");
		// devises.add(selectItem);
		//
		// selectItem = new SelectItem();
		// selectItem.setValue("JPY");
		// selectItem.setLabel("Yen");
		// devises .add(selectItem);
		return devises;
	}

	public String getDevise() {
		return devise;
	}

	public void setDevise(String devise) {
		this.devise = devise;
	}

	public double getMontantAutreDevise() {
		montantAutreDevise = this.montantTotalCommande * this.tauxAutreDevise;
		return montantAutreDevise;
	}

	/**
	 * en cas de changement de devise,
	 * on recupere le nouveau taux de change et
	 * on recalcule le montant total de la commande dans l'autre devise
	 */
	public void onChangeDevise() {
		String tauxChange;
		System.out.println(devise);
		tauxChange = Utils.getStringContentByURL(cheminWSExchange + strRate
				+ "/" + devise);
		this.tauxAutreDevise = Double.valueOf(tauxChange).doubleValue();
		montantAutreDevise = this.montantTotalCommande * tauxAutreDevise;
	}
}
